import type { 
  ModelProvider, 
  ChatMessage, 
  ChatCompletionRequest, 
  ChatCompletionResponse, 
  AIServiceConfig 
} from '@/types/ai-models'
import { AI_PROVIDERS, getProviderById, getModelById } from '@/config/ai-providers'

export class AIService {
  private config: AIServiceConfig = {
    currentProvider: 'deepseek',
    apiKeys: {},
    settings: {
      temperature: 0.7,
      maxTokens: 2048,
      topP: 0.9
    }
  }

  constructor() {
    this.loadConfig()
    this.loadApiKeysFromEnv()
  }

  private loadConfig(): void {
    const saved = localStorage.getItem('ai-service-config')
    if (saved) {
      this.config = { ...this.config, ...JSON.parse(saved) }
    }
  }

  private saveConfig(): void {
    localStorage.setItem('ai-service-config', JSON.stringify(this.config))
  }

  private loadApiKeysFromEnv(): void {
    AI_PROVIDERS.forEach(provider => {
      const envValue = import.meta.env[provider.apiKeyEnvVar]
      if (envValue) {
        this.config.apiKeys[provider.id] = envValue
      }
    })
    
  }

  public setCurrentProvider(providerId: string): boolean {
    const provider = getProviderById(providerId)
    if (!provider) {
      console.error(`Provider ${providerId} not found`)
      return false
    }
    
    this.config.currentProvider = providerId
    this.saveConfig()
    return true
  }

  public getCurrentProvider(): ModelProvider | null {
    return getProviderById(this.config.currentProvider) || null
  }

  public getAvailableProviders(): ModelProvider[] {
    return AI_PROVIDERS
  }

  public setApiKey(providerId: string, apiKey: string): void {
    this.config.apiKeys[providerId] = apiKey
    this.saveConfig()
  }

  public getApiKey(providerId?: string): string | null {
    const targetProvider = providerId || this.config.currentProvider
    return this.config.apiKeys[targetProvider] || null
  }

  public updateSettings(settings: Partial<typeof this.config.settings>): void {
    this.config.settings = { ...this.config.settings, ...settings }
    this.saveConfig()
  }

  public getSettings() {
    return { ...this.config.settings }
  }

  private async makeRequest(
    provider: ModelProvider, 
    apiKey: string, 
    payload: ChatCompletionRequest
  ): Promise<ChatCompletionResponse> {
    const headers: Record<string, string> = {
      'Content-Type': 'application/json'
    }

    // 不同提供商的认证方式
    switch (provider.id) {
      case 'qwen':
        headers['Authorization'] = `Bearer ${apiKey}`
        break
      case 'doubao':
        headers['Authorization'] = `Bearer ${apiKey}`
        break
      case 'deepseek':
        headers['Authorization'] = `Bearer ${apiKey}`
        break
      default:
        headers['Authorization'] = `Bearer ${apiKey}`
    }

    const response = await fetch(`${provider.baseURL}/chat/completions`, {
      method: 'POST',
      headers,
      body: JSON.stringify(payload)
    })

    if (!response.ok) {
      const error = await response.text()
      throw new Error(`API request failed: ${response.status} ${error}`)
    }

    return await response.json()
  }

  public async chat(
    messages: ChatMessage[], 
    options: {
      model?: string
      provider?: string
      temperature?: number
      maxTokens?: number
      stream?: boolean
    } = {}
  ): Promise<ChatCompletionResponse> {
    const provider = getProviderById(options.provider || this.config.currentProvider)
    if (!provider) {
      throw new Error('No valid provider selected')
    }

    const apiKey = this.getApiKey(provider.id)
    if (!apiKey) {
      throw new Error(`No API key configured for provider: ${provider.name}`)
    }

    const model = options.model || provider.defaultModel
    
    const modelInfo = getModelById(provider.id, model)
    
    const payload: ChatCompletionRequest = {
      model,
      messages,
      temperature: options.temperature ?? this.config.settings.temperature,
      max_tokens: Math.min(
        options.maxTokens ?? this.config.settings.maxTokens,
        modelInfo?.maxTokens ?? 4096
      ),
      top_p: this.config.settings.topP,
      stream: options.stream ?? false
    }

    return await this.makeRequest(provider, apiKey, payload)
  }

  public async quickChat(
    content: string, 
    systemPrompt?: string, 
    options?: { provider?: string; model?: string }
  ): Promise<string> {
    const messages: ChatMessage[] = []
    
    if (systemPrompt) {
      messages.push({ role: 'system', content: systemPrompt })
    }
    
    messages.push({ role: 'user', content })

    const response = await this.chat(messages, options)
    return response.choices[0]?.message?.content || ''
  }

  public async switchAndChat(
    providerId: string, 
    messages: ChatMessage[], 
    options: { model?: string } = {}
  ): Promise<ChatCompletionResponse> {
    const originalProvider = this.config.currentProvider
    
    try {
      if (!this.setCurrentProvider(providerId)) {
        throw new Error(`Failed to switch to provider: ${providerId}`)
      }
      
      return await this.chat(messages, options)
    } finally {
      // 恢复原来的提供商
      this.setCurrentProvider(originalProvider)
    }
  }

  public calculateTokenCost(
    provider: ModelProvider, 
    model: string, 
    inputTokens: number, 
    outputTokens: number
  ): number {
    const modelInfo = getModelById(provider.id, model)
    if (!modelInfo?.pricing) return 0

    const inputCost = (inputTokens / 1000) * modelInfo.pricing.input
    const outputCost = (outputTokens / 1000) * modelInfo.pricing.output
    
    return inputCost + outputCost
  }

  public getProviderStatus(): Record<string, { hasApiKey: boolean; isActive: boolean }> {
    const status: Record<string, { hasApiKey: boolean; isActive: boolean }> = {}
    
    AI_PROVIDERS.forEach(provider => {
      status[provider.id] = {
        hasApiKey: !!this.getApiKey(provider.id),
        isActive: provider.id === this.config.currentProvider
      }
    })
    
    return status
  }
}

// 单例模式
export const aiService = new AIService()